/**
 * Created by three on 14-8-6.
 */
'use strict';
(function (app) {
    /**
     * 系统配置服务service
     * 1、提供app初始化配置参数
     * 2、加载初始化数据
     * 3、提供app运行时，访问配置选项
     */
    app.provider('config', ["$httpProvider", function ($httpProvider) {
        var configProvider = this;
        configProvider.RestfulApiConf = [
            { name: 'DemoService', url: 'http://www.baidu.com', type: 'http' }
        ];
        configProvider.configProps = function () {
            $httpProvider.defaults.withCredentials = true;
            configProvider.properties.ajaxXhrFields = {
                withCredentials: true
            };
            configProvider.properties.asyncInitializeProps = [
                {
                    name: 'menuData',
                    url:"data/menu.json",
                    method: 'GET',
                    params: {}
                }
            ];
        };
        configProvider.properties = {};

        this.$get = ['$rootScope','$http','$q','logger', function ($rootScope,$http,$q,logger) {
            var config = {
                //                events message data format:
                //                {
                //                    type:'',
                //                    data:{},
                //                    callback: function() {} // {}
                //                }
                events: {
                    loading: 'loadingEvent',
                    showMsg: 'showMessageEvent',
                    showBox: 'showBoxEvent',
                    logout: 'logoutEvent'
                },
                asyncData: {},
                asyncInitialize: function () { // 从后端加载初始化数据，服务器端返回json数据
                    var count = configProvider.properties.asyncInitializeProps.length;
                    var _allPromise = [];
                    for (var i = 0; i < count; i++) {
                        (function (prop) {
                            var q = $q.defer();
                            config.asyncData[prop.name] = q.promise;
                            _allPromise.push(q.promise);

                            logger.info("开始加载异步初始化数据：" + prop.name + "[" + prop.url + "]");
                            $http(prop).success(function (data) {
                                q.resolve(data);
                                logger.info("["+prop.name+"]数据加载完成！")
                            }).error(function (err) {
                                q.reject(err);
                                logger.error("["+prop.name+"]数据加载失败！");
                                logger.log(arguments)
                            });
                        }(configProvider.properties.asyncInitializeProps[i]));
                    }
                    config.asyncData._all = $q.all(_allPromise);
                },
                properties: configProvider.properties,
                data_serve_base_url: 'http://127.0.0.1:8080',
                notify_url: 'http://127.0.0.1:9091',
                upload_url: ".",
                langConf: {
                    langPath: 'langs/',
                    defaultLang: 'zh-CN',
                    langMap: {
                        'zh-CN': 'zh.json',
                        'en-US': 'en.json'
                    }
                }
            };
            return config;
        }];
    }])
        .factory('HttpErrorHandlerConfig', ['$injector', '$q', '$rootScope', '$location', 'Config', function ($injector, $q, $rootScope, $location, config) {
            return {
                error: function (code, data) {
                    var name = 'E' + code;
                    var hasHandler = name in this.errorHandlers;

                    var handler = hasHandler ? this.errorHandlers[name] : this.errorHandlers['UnkownError'];
                    return handler(data);
                },
                errorHandlers: {
                    UnkownError: function (response) {
                        $rootScope.$emit(config.events.showMsg, {
                            type: 'berror',
                            title: '请求错误',
                            content: (response.data == null || response.data == '') ? '服务器未知，请联系管理员！' : response.data,
                            config: {},
                            callback: function () {
                            }
                        });
                        $rootScope.$emit(config.events.loading, {type: 'loaded'});
                        $rootScope.$emit(config.events.loading, {type: 'LoadedModal'});
                    },
                    E404: function (response) {
                        $rootScope.$emit(config.events.showMsg, {
                            type: 'berror',
                            title: '页面没有找到',
                            content: "没有找到你要的页面：" + response.config.url + "<br>\
                                页面被移动或者删除，具体信息请联系管理员！<br>\
                                如果发现此提示框，希望能尽快给我们反馈！<br>\
                                使用愉快！",
                            config: {},
                            callback: function () {
                            }
                        });
                        $rootScope.$emit(config.events.loading, {type: 'loaded'});
                        $rootScope.$emit(config.events.loading, {type: 'LoadedModal'});
                        // 返回 404 信息
                        var $http = $injector.get('$http');
                        return $http.get('views/404.html');
                    },
                    E401: function (response) {
                        $rootScope.$emit(config.events.showMsg, {
                            type: 'berror',
                            title: '没有登录',
                            content: "即将转到登录页面",
                            config: {},
                            callback: function () {
                                $rootScope.$emit(config.events.loading, {type: 'loaded'})
                            }
                        });
                        //  没有登录，跳转到登录页面
                        location.href = 'login.html';
                    },
                    E403: function (response) {
                        $rootScope.$emit(config.events.showMsg, {
                            type: 'berror',
                            title: '权限错误',
                            content: (response.data == null || response.data == '') ? '你没有访问该资源权限，请联系管理员！' : response.data,
                            config: {},
                            callback: function () {
                            }
                        });
                        $rootScope.$emit(config.events.loading, {type: 'loaded'});
                        $rootScope.$emit(config.events.loading, {type: 'LoadedModal'});

                        // 返回 403 信息
                        // json请求
                        if (response.config.headers.Accept == 'application/json, text/javascript, */*') {
                            var $http = $injector.get('$http');
                            return $http.get('views/403.html');
                        } else { // 'application/json, text/plain, */*'
                            $location.path('/403');
                        }
                    },
                    E500: function (response) {
                        $rootScope.$emit(config.events.showMsg, {
                            type: 'berror',
                            title: '服务器内部错误',
                            content: "服务器内部错误：" + response.data + "<br>\
                                如果发现此提示框，希望能尽快给我们反馈！<br>\
                                使用愉快！",
                            config: {},
                            callback: function () {
                            }
                        });
                        $rootScope.$emit(config.events.loading, {type: 'loaded'});
                        $rootScope.$emit(config.events.loading, {type: 'LoadedModal'});
                        $location.path('/5xx');
                    }
                }
            };
        }])
    ;

    /**
     * 初始化ajax请求类型
     * @param httpProvider
     */
    function initAjaxRequestType(httpProvider) {
        // Use x-www-form-urlencoded Content-Type
        httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
        httpProvider.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
        httpProvider.defaults.withCredentials = true;

        /**
         * The workhorse; converts an object to x-www-form-urlencoded serialization.
         * @param {Object} obj
         * @return {String}
         */
        var param = function (obj) {
            var query = '', name, value, fullSubName, subName, subValue, innerObj, i;

            for (name in obj) {
                value = obj[name];

                if (value instanceof Array) {
                    for (i = 0; i < value.length; ++i) {
                        subValue = value[i];
                        fullSubName = name + '[' + i + ']';
                        innerObj = {};
                        innerObj[fullSubName] = subValue;
                        query += param(innerObj) + '&';
                    }
                }
                else if (value instanceof Object) {
                    for (subName in value) {
                        subValue = value[subName];
                        fullSubName = name + '[' + subName + ']';
                        innerObj = {};
                        innerObj[fullSubName] = subValue;
                        query += param(innerObj) + '&';
                    }
                }
                else if (value !== undefined && value !== null)
                    query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
            }

            return query.length ? query.substr(0, query.length - 1) : query;
        };

        // Override $http service's default transformRequest
        httpProvider.defaults.transformRequest = [function (data) {
            return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
        }];
    }
}(angular.module('app.common.config')));
